package schema

import (
	"container/list"
)

/**
 * Key metadata information including name, number of columns and page number, etc.
 * <pre>
 * MySQL 5.7:  SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES;
 * MySQL 8.0+: SELECT * FROM INFORMATION_SCHEMA.INNODB_INDEXES;
 * +----------+----------+----------+------+----------+---------+-------+
 * | INDEX_ID | NAME     | TABLE_ID | TYPE | N_FIELDS | PAGE_NO | SPACE |
 * +----------+----------+----------+------+----------+---------+-------+
 * |       11 | ID_IND   |       11 |    3 |        1 |     302 |     0 |
 * |       12 | FOR_IND  |       11 |    0 |        1 |     303 |     0 |
 * ...
 * </pre>
 *
 * @author xu.zx
 */

type KeyMeta struct {
	Name string

	/**
	 * Key type.
	 */
	KeyMeta Type

	/**
	 * Number of columns, should be greater than 0.
	 */
	NumOfColumns int64

	KeyColumns           list.List // List<Column>
	KeyColumnNames       list.List // List<String>
	KeyVarLenColumns     list.List // List<Column>
	KeyVarLenColumnNames list.List // List<String>

	/**
	 * key length might be different from column definition, for example,
	 * column <code>address varchar(500)</code> will have key as <code>varchar(255)</code>;
	 */
	KeyVarLen list.List // List<Integer>

}

type Type struct {
	/**
	 * Key type.
	 */
	PRIMARY_KEY  string //"PRIMARY KEY"
	KEY          string //"KEY"
	INDEX        string //"INDEX"
	UNIQUE_KEY   string //"UNIQUE KEY"
	UNIQUE_INDEX string //"UNIQUE INDEX"
	FULLTEXT_KEY string //"FULLTEXT KEY"
	FOREIGN_KEY  string //"FOREIGN KEY"
}

func NewDefaultType() Type {
	return Type{
		"PRIMARY KEY",
		"KEY",
		"INDEX",
		"UNIQUE KEY",
		"UNIQUE INDEX",
		"FULLTEXT KEY",
		"FOREIGN KEY",
	}
}

func containsColumn(columnName string, meta KeyMeta) bool {
	for i := meta.KeyColumnNames.Front(); i != nil; i = i.Next() {
		if i.Value.(string) == columnName {
			return true
		}
	}
	return false
}
